package model.map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import model.Model;
import model.effect.ConstantChangeStatEffect;
import model.effect.Effect;
import model.effect.FlowEffect;
import model.effect.LevelUpEffect;
import model.effect.TeleportEffect;
import model.entity.Avatar;
import model.entity.BasicEntity;
import model.entity.MerchantNPC;
import model.entity.Mountable;
import model.entity.MountableNPC;
import model.entity.NPC;
import model.entity.Occupation;
import model.entity.OccupationLibrary;
import model.entity.Vehicle;
import model.entity.brain.AggressiveBrain;
import model.entity.brain.DumbBrain;
import model.entity.brain.PetBrain;
import model.entity.brain.WanderingBrain;
import model.entity.stats.Stat;
import model.entity.stats.StatSet;
import model.entity.stats.StatType;
import model.interactionHandlerInitializer.InteractionHandlerInitializer;
import model.interactionHandlerInitializer.InteractionNames;
import model.interactionHandlerInitializer.MountHandlerInitializer;
import model.interactionHandlerInitializer.PickpocketHandlerInitializer;
import model.interactionHandlerInitializer.TalkHandlerInitializer;
import model.interactionhandler.BasicEntityHasInteractionInitializer;
import model.item.EquipmentSlot;
import model.item.EquipmentType;
import model.item.EquippableItem;
import model.item.EquippedInventory;
import model.item.Inventory;
import model.item.Item;
import model.item.ItemLibrary;
import model.item.OneShotItem;
import model.item.TakeableItem;
import model.skill.AngularProjectile;
import model.skill.LinearProjectile;
import model.skill.Projectile;
import model.skill.RadialProjectile;
import utilities.*;

/**
 * This class holds the maps and the list of entities that make up each level map in the game. 
 */
public class GameMap extends Model implements Archiveable {
	
	private FogOfWar fogOfWar;
	private List<BasicEntity> entities;
	private List<Mountable> vehicles;
	private Map<Location, Obstacle> obstacleMap;
	private Map<Location, Terrain> terrainMap;
	private Map<Location, Decal> decalMap;
	private Map<Location, Item> itemMap;
	private Map<Location, Projectile> projectileMap;
	private Map<Location, AreaEffect> areaeffectMap;
	private FogOfWar fog = new FogOfWar(this, null, new HexLocationProjection()); //TODO The middle bit.
	
	private int maxX;
	private int maxY;
	
	private int minX;
	private int minY;
	
	/* --------------------------------------------------------------------------------
	 * Constructors
	   -------------------------------------------------------------------------------- */

	/**
	 * Returns a default map, used for testing
	 */
	public GameMap()
	{
		super("Test");
		fogOfWar = new FogOfWar(this, World.getInstance().getPlayer(), new HexLocationProjection() );
		entities = new ArrayList<BasicEntity>();
		vehicles = new ArrayList<Mountable>();
		terrainMap = new HashMap<Location, Terrain>();
		decalMap = new HashMap<Location, Decal>();
		itemMap = new HashMap<Location, Item>();
		projectileMap = new HashMap<Location, Projectile>();
		areaeffectMap = new HashMap<Location, AreaEffect>();
		obstacleMap = new HashMap<Location, Obstacle>();
		
		maxX = 40;
		maxY = 40;
		
		minY = 0;
		minX = 0;
		
		for(int i = minY; i <= maxX; i++)
		{
			for(int j = minY; j <= 10; j++)
			{
				terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
			}
			
			for(int j = 11; j <= 30; j++)
			{
				if(i <= 10)
				{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
				} else if( i >= 30)
				{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
				} else
				{
					terrainMap.put(new Location(i, j), new Terrain("Grass", MovementType.GRASS));
				}
			}
			
			for(int j = 31; j <= 40; j++)
			{
				terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
			}
		}
		
		obstacleMap.put( new Location (10,10), new Obstacle("obstacle") );
		this.areaeffectMap.put( new Location(11,11), new AreaEffect("areaEffect", new LevelUpEffect("levelup", 1) ) );
		this.decalMap.put( new Location(12,12), new Decal("decal") );
		
//		this.entities.add( new NPC("entity", Direction.S, new Location(13,13), null, null, null, null, null, false) );
		
		
		StatSet statSet3 = new StatSet();
		statSet3.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		statSet3.addStat(StatType.HP, new Stat(100, StatType.HP));
		Inventory inv3 = new Inventory();
		inv3.addItem(new TakeableItem("anItem"));
		inv3.addItem(new TakeableItem("theItem"));
		ArrayList<String> dialogue = new ArrayList<String>();
		dialogue.add("first message");
		dialogue.add("second message");
		dialogue.add("third and last message");
		MerchantNPC npcMerchant = new MerchantNPC("entity", Direction.S, new Location(25,25), statSet3, null, inv3, null, null, false, new DumbBrain(null), dialogue);
//		NPC npc = new NPC("entity", Direction.S, new Location(13,13), null, null, null, null, null, false, new DumbBrain(null));
		this.entities.add(npcMerchant);
		
		StatSet statSet2 = new StatSet();
		statSet2.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		statSet2.addStat(StatType.HP, new Stat(100, StatType.HP));
		Inventory inv = new Inventory();
		inv.addItem(new TakeableItem("anItem"));
		inv.addItem(new TakeableItem("theItem"));
		
		List<MovementType> movtyps = new ArrayList<MovementType>();
		movtyps.add(MovementType.GRASS);
		//NPC npc = new NPC("entity", Direction.S, new Location(13,13), statSet2, null, inv, new EquippedInventory(), null, false, new DumbBrain(null));
		MountableNPC npc = new MountableNPC("entity", Direction.S, new Location(13,13), statSet2, movtyps, inv, new EquippedInventory(), null, false, new DumbBrain(null));
		this.entities.add(npc);
		List<InteractionHandlerInitializer> inits = new ArrayList<InteractionHandlerInitializer>();
		BasicEntityHasInteractionInitializer.getInstance().addRelation( npcMerchant , inits);
		//inits.add( new TalkHandlerInitializer(InteractionNames.TALK));
		inits.add( new MountHandlerInitializer(InteractionNames.MOUNT));
		BasicEntityHasInteractionInitializer.getInstance().addRelation( npc, inits);
		
		
		
		Effect effect = new ConstantChangeStatEffect("Damage", StatType.HP, -100);
		Location location = new Location(20,20);
		LocationProjection hex = new HexLocationProjection(); 
		RadialProjectile linear = new RadialProjectile("projectile", effect, hex, 15, 15);		
		
		this.itemMap.put( new Location(14,14), new EquippableItem("item", null, "item", null, null, 1) );
		
		this.itemMap.put( location, new OneShotItem("item", linear));
		
		//this.projectileMap.put( new Location(15,15), new Projectile("projectile", null, Direction.S, new Location(15, 15), null));
		this.vehicles.add(new Vehicle("vehicle", Direction.S, new Location(16,16), null,null,null, null));
		
		
		ArrayList<MovementType> mt = new ArrayList<MovementType>();
		mt.add( MovementType.GRASS );
		StatSet stats = new StatSet();
		StatSet statSet = new StatSet();
		statSet.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		statSet.addStat(StatType.HP, new Stat(100, StatType.HP));
		//NPC npc1 = new NPC("entity", Direction.S, new Location(18,13), statSet, mt, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		//npc1.setBrain( new WanderingBrain( World.getInstance().getPlayer(), npc1) );
//		npc1.setBrain( new DumbBrain( npc1 ) );
		//this.entities.add(npc1);
	}
	
	
	/**
	 * actual constructor for map
	 */
	public GameMap(String name){
		super(name);
		if(name.equals("GameMap")){
			initGameMap();
		}
		else if(name.equals("BattleMap")){
			initBattleMap();
		}
	}
	
	private void initGameMap(){
		entities = new ArrayList<BasicEntity>();
		vehicles = new ArrayList<Mountable>();
		terrainMap = new HashMap<Location, Terrain>();
		decalMap = new HashMap<Location, Decal>();
		itemMap = new HashMap<Location, Item>();
		projectileMap = new HashMap<Location, Projectile>();
		areaeffectMap = new HashMap<Location, AreaEffect>();
		obstacleMap = new HashMap<Location, Obstacle>();
		
		maxX = 40;
		maxY = 40;
		
		minY = 0;
		minX = 0;
		
		ItemLibrary il = new ItemLibrary();
		il.initLibrary();
		
		for(int i = minY; i <= maxX; i++)
		{
			for(int j = minY; j <= 10; j++)
			{
				terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
			}
			
			for(int j = 11; j <= 30; j++)
			{
				if(i <= 10)
				{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
				} else if( i >= 30)
				{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
				} else
				{
					terrainMap.put(new Location(i, j), new Terrain("Grass", MovementType.GRASS));
					if( i == 28 || i == 29 || i == 27){
						terrainMap.put(new Location(i, j), new Terrain("Water", MovementType.WATER));
						areaeffectMap.put(new Location(i, j), new AreaEffect("FlowEffect", new FlowEffect("FlowEffect", Direction.SE, 1)));
					}
					else if (j == 15 || j ==16){
						terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
					}
					if( j == 30 ){
						itemMap.put(new Location(i, j), ItemLibrary.getTakeableItem("slimePotion"));
					}
				}
			}	
			for(int j = 31; j <= 40; j++)
			{
				terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
			}
		}
		// effects
		areaeffectMap.put(new Location(14,18), new AreaEffect("redTile", new TeleportEffect("TeleportEffect", new Location(12,13))));
		areaeffectMap.put(new Location(19, 18), new AreaEffect("damage_ae", new ConstantChangeStatEffect("DamageEffect", StatType.HP, -10)));;	
		// obstacles
		obstacleMap.put(new Location(14,19), new Obstacle("Tree"));
		obstacleMap.put(new Location(14,17), new Obstacle("Tree"));
		obstacleMap.put(new Location(13,17), new Obstacle("Tree"));
		obstacleMap.put(new Location(13,18), new Obstacle("Tree"));
		obstacleMap.put(new Location(13,19), new Obstacle("Tree"));
		obstacleMap.put(new Location(14,13), new Obstacle("Tree"));
		obstacleMap.put(new Location(14,14), new Obstacle("Tree"));
		
		OccupationLibrary.getInstance();
		StatSet stats = new StatSet();
		ArrayList<MovementType> mt = new ArrayList<MovementType>();
		mt.add( MovementType.GRASS );
		stats.addStat(StatType.MOVEMENTSPEED, new Stat(1, StatType.MOVEMENTSPEED));
		stats.addStat(StatType.SIGHTRANGE, new Stat(5, StatType.SIGHTRANGE ));
		stats.addStat(StatType.HP, new Stat(100, StatType.HP));
		Inventory inv = new Inventory();
		StatSet axe1Hstats = new StatSet();
		axe1Hstats.addStat(StatType.OFFENSIVERATING, new Stat(20, StatType.STRENGTH));
		EquippableItem axe1H = new EquippableItem("Axe1H", null, EquipmentType.ONEHANDED, EquipmentSlot.RIGHT_HAND, axe1Hstats , 100);
		inv.addItem(axe1H);
		inv.addItem(axe1H);
		NPC npc1 = new NPC("entity1", Direction.S, new Location(18,20), stats, mt, inv, new EquippedInventory(), OccupationLibrary.getOccupation("smasherOccupation"), false, null);
		//npc1.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc1) );
		npc1.setBrain( new DumbBrain( npc1) );
		this.entities.add(npc1);
		List<InteractionHandlerInitializer> interacts = new ArrayList<InteractionHandlerInitializer>();
		interacts.add(new PickpocketHandlerInitializer("Pickpocket"));
		BasicEntityHasInteractionInitializer.getInstance().addRelation(npc1, interacts);
		
		stats = new StatSet();
		stats.addStat(StatType.MOVEMENTSPEED, new Stat(1, StatType.MOVEMENTSPEED));
		stats.addStat(StatType.HP, new Stat(60, StatType.HP));
		mt = new ArrayList<MovementType>();
		mt.add(MovementType.GRASS);
		mt.add(MovementType.WATER);
		inv = new Inventory();
		StatSet Spear2Hstats = new StatSet();
		Spear2Hstats.addStat(StatType.OFFENSIVERATING, new Stat(10, StatType.STRENGTH));
		Spear2Hstats.addStat(StatType.OFFENSIVERATING, new Stat(2, StatType.AGILITY));
		EquippableItem spear2H = new EquippableItem("Spear2H", null, EquipmentType.TWOHANDED, EquipmentSlot.RIGHT_HAND, Spear2Hstats , 100);
		inv.addItem(spear2H);
		inv.addItem(spear2H);
		MountableNPC npc2 = new MountableNPC("octopus", Direction.S, new Location(18,13), stats, mt, inv, new EquippedInventory(), OccupationLibrary.getOccupation("smasherOccupation"), false, null);
		npc2.setBrain( new WanderingBrain( World.getInstance().getPlayer(), npc2) );
		this.entities.add(npc2);
		interacts = new ArrayList<InteractionHandlerInitializer>();
		interacts.add(new MountHandlerInitializer("Mount"));
		BasicEntityHasInteractionInitializer.getInstance().addRelation(npc2, interacts);
		
		StatSet vehSt = new StatSet();
		vehSt.addStat(StatType.MOVEMENTSPEED, new Stat(15, StatType.MOVEMENTSPEED));
		vehSt.addStat(StatType.HP, new Stat(999999, StatType.HP));
		mt = new ArrayList<MovementType>();
		mt.add(MovementType.GRASS);
		MountableNPC veh = new MountableNPC("sk8board", Direction.N, new Location(15,19), vehSt, mt, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		veh.setBrain(new DumbBrain(veh));
		this.vehicles.add(veh);
		interacts = new ArrayList<InteractionHandlerInitializer>();
		interacts.add(new MountHandlerInitializer("Mount"));
		BasicEntityHasInteractionInitializer.getInstance().addRelation(veh, interacts);
		
		// items
		itemMap.put(new Location(15,14), ItemLibrary.getEquippableItem("ThunderStaff"));
		itemMap.put(new Location(22,20), ItemLibrary.getEquippableItem("LongbowRanged"));
		itemMap.put(new Location(22,21), ItemLibrary.getTakeableItem("slimePotion"));
		itemMap.put(new Location(22,21), ItemLibrary.getTakeableItem("slimePotion"));
	
		World.getInstance().addMap(this);
		World.getInstance().setCurrentMap(this);
		
		
		StatSet statSet3 = new StatSet();
		statSet3.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		statSet3.addStat(StatType.HP, new Stat(100, StatType.HP));
		Inventory inv3 = new Inventory();
		inv3.addItem(new TakeableItem("anItem"));
		inv3.addItem(new TakeableItem("theItem"));
		ArrayList<String> dialogue = new ArrayList<String>();
		dialogue.add("Hey, I herd that team Kraken used Serializable.");
		dialogue.add("Hey, I herd team Chiron has a god object");
		dialogue.add("Hey, I herd team Minotaur used conditional logic.");
		dialogue.add("Hey, I herd 3d is overrated");
		interacts = new ArrayList<InteractionHandlerInitializer>();
		interacts.add(new TalkHandlerInitializer("TalkButton"));
		MerchantNPC npcMerchant = new MerchantNPC("entity", Direction.S, new Location(20,24), statSet3, null, inv3, null, null, false, new DumbBrain(null), dialogue);
		this.entities.add(npcMerchant);
		BasicEntityHasInteractionInitializer.getInstance().addRelation(npcMerchant, interacts);
	}

	private void initBattleMap(){
		entities = new ArrayList<BasicEntity>();
		vehicles = new ArrayList<Mountable>();
		terrainMap = new HashMap<Location, Terrain>();
		decalMap = new HashMap<Location, Decal>();
		itemMap = new HashMap<Location, Item>();
		projectileMap = new HashMap<Location, Projectile>();
		areaeffectMap = new HashMap<Location, AreaEffect>();
		obstacleMap = new HashMap<Location, Obstacle>();
			
		maxX = 20;
		maxY = 20;
			
		minY = 0;
		minX = 0;
			
		for(int i = minY; i <= maxX; i++)
		{
			for(int j = minY; j <= 5; j++)
			{
				terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
			}
				
			for(int j = 6; j <= 15; j++)
			{
				if(i <= 5)
				{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
				} else if( i >= 15)
				{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
				} else
				{
					terrainMap.put(new Location(i, j), new Terrain("Grass", MovementType.GRASS));
				}
			}
				
			for(int j = 16; j <= 20; j++)
			{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
			}
		}
		World.getInstance().addMap(this);
		World.getInstance().setBattleMap(this);
		
		List<MovementType> movtyps = new ArrayList<MovementType>();
		movtyps.add(MovementType.GRASS);
		movtyps.add(MovementType.WATER);
		
		StatSet stats = new StatSet();
		
		stats.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		stats.addStat(StatType.SIGHTRANGE, new Stat(5, StatType.SIGHTRANGE ));
		stats.addStat(StatType.HP, new Stat(100, StatType.HP));
		
		NPC pet = new NPC("Pet", Direction.S, new Location(12,12), stats, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
        pet.setBrain( new PetBrain( World.getInstance().getPlayer(), pet, World.getInstance().getCurrentMap()) );
        World.getInstance().getCurrentMap().addEntity(pet);
	}
	
	/**
	 * Returns a vinnys default map, used for testing
	 */
	public GameMap(int p)
	{
		super("Test");
		entities = new ArrayList<BasicEntity>();
		vehicles = new ArrayList<Mountable>();
		terrainMap = new HashMap<Location, Terrain>();
		decalMap = new HashMap<Location, Decal>();
		itemMap = new HashMap<Location, Item>();
		projectileMap = new HashMap<Location, Projectile>();
		areaeffectMap = new HashMap<Location, AreaEffect>();
		obstacleMap = new HashMap<Location, Obstacle>();
		
		StatSet stats = new StatSet();
		StatSet statSet = new StatSet();
		
		maxX = 40;
		maxY = 40;
		
		minY = 0;
		minX = 0;
		
		for(int i = minY; i <= maxX; i++)
		{
			for(int j = minY; j <= 10; j++)
			{
				terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
			}
			
			for(int j = 11; j <= 30; j++)
			{
				if(i <= 10)
				{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
				} else if( i >= 30)
				{
					terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
				} else
				{
					terrainMap.put(new Location(i, j), new Terrain("Grass", MovementType.GRASS));
					this.itemMap.put( new Location(i,j), new EquippableItem("item", null, "item", EquipmentSlot.HEAD, statSet, 1) );
				}
			}
			
			for(int j = 31; j <= 40; j++)
			{
				terrainMap.put(new Location(i, j), new Terrain("Unpassable", MovementType.UNPASSABLE));
			}
		}
		
		obstacleMap.put( new Location (10,10), new Obstacle("obstacle") );
		this.areaeffectMap.put( new Location(11,11), new AreaEffect("damage_ae",  new ConstantChangeStatEffect("Damage", StatType.HP, -5)));
		this.decalMap.put( new Location(12,12), new Decal("decal") );
		
		ArrayList<MovementType> mt = new ArrayList<MovementType>();
		mt.add( MovementType.GRASS );
		//StatSet stats = new StatSet();
		stats.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		stats.addStat(StatType.SIGHTRANGE, new Stat(5, StatType.SIGHTRANGE ));
		stats.addStat(StatType.HP, new Stat(100, StatType.HP));
		
		Avatar avatar = new Avatar("entity", Direction.S, new Location(11,13), stats, mt , new Inventory(), new EquippedInventory(), new Occupation(), false);
		addEntity(avatar);
		World.getInstance().setPlayer( avatar );
		
		FogOfWar fow = new FogOfWar( this, avatar, new HexLocationProjection());
		
//		this.entities.add( new NPC("entity", Direction.S, new Location(13,13), null, null, null, null, null, false) );
		List<MovementType> movtyps = new ArrayList<MovementType>();
		movtyps.add(MovementType.GRASS);
		//StatSet statSet = new StatSet();
	
		statSet.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		statSet.addStat(StatType.HP, new Stat(60, StatType.HP));
		/*
		NPC npc1 = new NPC("entity", Direction.S, new Location(18,13), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		//npc1.setBrain( new WanderingBrain( World.getInstance().getPlayer(), npc1) );
		npc1.setBrain( new DumbBrain( npc1 ) );
		this.entities.add(npc1);
		*/
		
		NPC npc2 = new NPC("entity", Direction.S, new Location(20,13), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc2.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc2) );
		this.entities.add(npc2);
		/*
		NPC npc3 = new NPC("entity", Direction.S, new Location(13,16), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc3.setBrain( new WanderingBrain( World.getInstance().getPlayer(), npc3) );
		this.entities.add(npc3);
		NPC npc4 = new NPC("satan", Direction.S, new Location(14,18), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc4.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc4) );
		this.entities.add(npc4);
		NPC npc5 = new NPC("entity", Direction.S, new Location(14,19), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc5.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc5) );
		this.entities.add(npc5);
		NPC npc6 = new NPC("satan", Direction.S, new Location(15,19), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc6.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc6) );
		this.entities.add(npc6);
		NPC npc7 = new NPC("satan", Direction.S, new Location(17,19), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc7.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc7) );
		this.entities.add(npc7);
		NPC npc8 = new NPC("satan", Direction.S, new Location(14,20), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc8.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc8) );
		this.entities.add(npc8);
		NPC npc9 = new NPC("satan", Direction.S, new Location(14,20), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc9.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc9) );
		this.entities.add(npc9);
		NPC npc10 = new NPC("satan", Direction.S, new Location(14,20), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc10.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc10) );
		this.entities.add(npc10);
		NPC npc11 = new NPC("satan", Direction.S, new Location(14,20), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc11.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc11) );
		this.entities.add(npc11);
		NPC npc12 = new NPC("satan", Direction.S, new Location(14,20), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		npc12.setBrain( new AggressiveBrain( World.getInstance().getPlayer(), npc12) );
		this.entities.add(npc12);
		*/
		
		NPC pet = new NPC("Pet", Direction.S, new Location(15,17), statSet, movtyps, new Inventory(), new EquippedInventory(), new Occupation(), false, null);
		pet.setBrain( new PetBrain( World.getInstance().getPlayer(), pet, World.getInstance().getCurrentMap()) );
		this.entities.add(pet);
		List<InteractionHandlerInitializer> inits = new ArrayList<InteractionHandlerInitializer>();
		inits.add( new PickpocketHandlerInitializer("Pick-pocket"));
		BasicEntityHasInteractionInitializer.getInstance().addRelation( pet , inits);
		
		/*
		this.itemMap.put( new Location(17,17), new EquippableItem("item", null, "item", EquipmentSlot.HEAD, statSet, 1) );
		this.itemMap.put( new Location(17,18), new EquippableItem("item", null, "item", null, null, 1) );
		this.itemMap.put( new Location(17,19), new EquippableItem("item", null, "item", null, null, 1) );
		this.itemMap.put( new Location(18,17), new EquippableItem("item", null, "item", null, null, 1) );
		this.itemMap.put( new Location(18,18), new EquippableItem("item", null, "item", null, null, 1) );
		*/
		//this.projectileMap.put( new Location(15,15), new Projectile("projectile", null, Direction.S, new Location(15, 15), null));
		this.vehicles.add(new Vehicle("vehicle", Direction.S, new Location(16,16), null,null,null, null));		
	}
	
	
	/**
	 * @param entities
	 * @param vehicles
	 * @param terrainMap
	 * @param decalMap
	 * @param itemMap
	 * @param projectileMap
	 * @param areaeffectMap
	 * @param maxX
	 * @param maxY
	 */
	public GameMap(String name, List<BasicEntity> entities, List<Mountable> vehicles, Map<Location, Obstacle> obstacleMap,
			Map<Location, Terrain> terrainMap, Map<Location, Decal> decalMap,
			Map<Location, Item> itemMap,
			Map<Location, Projectile> projectileMap,
			Map<Location, AreaEffect> areaeffectMap, int maxX, int maxY, int minX, int minY) {
		super(name);
		this.entities = entities;
		this.vehicles = vehicles;
		this.terrainMap = terrainMap;
		this.obstacleMap = obstacleMap;
		this.decalMap = decalMap;
		this.itemMap = itemMap;
		this.projectileMap = projectileMap;
		this.areaeffectMap = areaeffectMap;
		this.maxX = maxX;
		this.maxY = maxY;
		this.minX = minX;
		this.minY = minY;
	}

	/* --------------------------------------------------------------------------------
	 * Getters and Setters
	   -------------------------------------------------------------------------------- */
	
	public FogOfWar getFogOfWar() {
		return this.fogOfWar;
	}
	
	public void setFogOfWar( FogOfWar fogOfWar ) {
		this.fogOfWar = fogOfWar;
	}
	
	public List<BasicEntity> getEntities() {
		return entities;
	}

	public List<Mountable> getVehicles() {
		return vehicles;
	}
	
	public void updateFodOfWar() {
		this.fogOfWar.update();
	}

	/* --------------------------------------------------------------------------------
	 * Class methods
	   -------------------------------------------------------------------------------- */
	
	/**
	 * This method returns the Terrain in the map at the specified location
	 * @param location The location being searched for
	 * @return The Terrain at the given Location
	 */
	public Terrain getTerrain(Location location)
	{
		return terrainMap.get(location);
	}
	
	/**
	 * This method returns the AreaEffect in the map at the specified location
	 * @param location The location being searched for
	 * @return The AreaEffect at the given Location
	 */
	public AreaEffect getAreaEffect(Location location)
	{
		return areaeffectMap.get(location);
	}
	
	/**
	 * This method returns the Decal in the map at the specified location
	 * @param location The location being searched for
	 * @return The Decal at the given location
	 */
	public Decal getDecal(Location location)
	{
		return decalMap.get(location);
	}
	
	/**
	 * This method returns the Obstacle in the map at the specified location
	 * @param location The location being searched for
	 * @return The Obstacle at the given location 
	 */
	public Obstacle getObstacle(Location location)
	{
		return obstacleMap.get(location);
	}
	
	/**
	 * This method returns the Projectile in the map at the specified location
	 * @param location The location being searched for
	 * @return The Projectile at the given location
	 */
	public Projectile getProjectile(Location location)
	{
		return projectileMap.get(location);
	}
	
	/**
	 * This method returns the Item in the map at the specified location
	 * @param location The location being searched for
	 * @return The Item at the given location 
	 */
	public Item getItem(Location location)
	{
		return itemMap.get(location);
	}
	
	/**
	 * This looks through all the entities contained in the map and, if an entity is at the specified location, it returns that entity
	 * @param location The location that is being checked if any entity is on it.
	 * @return The entity at the location specified, or null if no entity is at that location.
	 */
	public BasicEntity getEntity(Location location)
	{
		for(BasicEntity e : entities) {
			if (location.equals(e.getLocation())) {
				return e;
			}
		}
		return null;
	}
	
	/**
	 * This looks through all the vehicles contained in the map and, if a vehicle is at the specified location, it returns that vehicle
	 * @param location The location that is being checked if any vehicle is on it.
	 * @return The entity at the location specified, or null if no vehicle is at that location.
	 */
	public Mountable getMountable(Location location)
	{
		{
			for(Mountable m : vehicles) {
				if (location.equals(m.getLocation())) {
					return m;
				}
			}
			return null;
		}
	}
	
	public int getMaxX()
	{
		return maxX;
	}

	public int getMaxY()
	{
		return maxY;
	}

	/**
	 * This method returns whether if a specific location has an entity with a boolean result
	 * @param location The location being searched for
	 * @return TRUE or FALSE regarding that tile containing an Entity
	 */
	public boolean hasEntity(Location location) {
		for(BasicEntity e : entities) {
			if (location.equals(e.getLocation())) {
				return true;
			}
		}
		return false;
	}
	
	public boolean hasMountable(Location location) {
		for(Mountable m : vehicles) {
			if (location.equals(m.getLocation())) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * This method returns whether if a specific location has an item with a boolean result
	 * @param location The location being searched for
	 * @return TRUE or FALSE regarding that tile containing an Item
	 */
	public boolean hasItem(Location location) {
		return itemMap.get(location) != null;
	}
	
	/**
	 * This method returns whether if a specific location has an AreaEffect with a boolean result
	 * @param location The location being searched for
	 * @return TRUE or FALSE regarding that tile containing an AreaEffect
	 */
	public boolean hasAreaEffect(Location location) {
		return areaeffectMap.get(location) != null;
	}
	
	/**
	 * This method returns whether if a specific location has a Decal with a boolean result
	 * @param location The location being searched for
	 * @return TRUE or FALSE regarding that tile containing a Decal
	 */
	public boolean hasDecal(Location location) {
		return decalMap.get(location) != null;
	}
	
	/**
	 * This method returns whether if a specific location has an Obstacle with a boolean result
	 * @param location The location being searched for
	 * @return TRUE or FALSE regarding that tile containing an Obstacle
	 */
	public boolean hasObstacle(Location location) {
		return obstacleMap.get(location) != null;
	}
	
	/**
	 * This method returns whether if a specific location has a Projectile with a boolean result
	 * @param location The location being searched for
	 * @return TRUE or FALSE regarding that tile containing a Projectile
	 */
	public boolean hasProjectile(Location location) {
		return projectileMap.get(location) != null;
	}
	/**
	 * Removes the Item at the specified Location from the map.
	 * @param location The location the Item is at
	 * @return The Item being removed
	 */
	public Item removeItem(Location location)
	{
		return itemMap.remove(location);
	}
	
	public Projectile removeProjectile(Location location)
	{
		return projectileMap.remove(location);
	}

	/**
	 * For adding NPC's to the map
	 * @param e
	 */
	public void addEntity(BasicEntity e){
		entities.add(e);
	}
	
	public void addVehicle(Mountable m){ //TODO: Ain't nothing can be done about this cast, is there?
		vehicles.add(m);
	}

	public void addAreaEffect(Location l, AreaEffect a){ 
		areaeffectMap.put(l,a);
	}
	
	public void addProjectile(Location l, Projectile p){ 
		projectileMap.put(l, p);
	}
	
	public void removeEntity(BasicEntity e)
	{
		entities.remove(e);
	}
	
	public void removeVehicle(Mountable m)
	{
		vehicles.remove(m);
	}
	
	/**
	 * For adding Items to the map
	 * @param i
	 * @param loc
	 */
	public void addItem(Location loc, Item i){
		itemMap.put(loc,i);
	}
	
	/**
	 * Checks if a location is within the boundary of the map
	 * @param loc The location to be checked
	 * @return TRUE if the location is within the bounds of the map, FALSE if the location is not.
	 */
	public boolean exists(Location loc)
	{
		if(loc.getX() > maxX)
		{
			return false;
		} else if(loc.getX() < minX)
		{
			return false;
		} else if(loc.getY() > maxY)
		{
			return false;
		} else if(loc.getY() < minY)
		{
			return false;
		}
		
		return true;
	}
	
	public void updateFogOfWar()
	{
		fog.update();
	}
	
	@Override
	public String toString()
	{
		return super.toString() + "GameMap [entities=" + entities + ", vehicles=" + vehicles + ", obstacleMap=" + obstacleMap
				+ ", terrainMap=" + terrainMap + ", decalMap=" + decalMap + ", itemMap=" + itemMap + ", projectileMap="
				+ projectileMap + ", areaeffectMap=" + areaeffectMap + ", maxX=" + maxX + ", maxY=" + maxY + "]";
	}
	
	
	public Archive save() {
		Archive archive = super.save();
		
		List<String> entitiesClassList = new ArrayList<String>();
		for (BasicEntity entity : this.entities) {
			entitiesClassList.add(entity.getClass().getName());
		}
		archive.putAttributeList("entitiesClassList", entitiesClassList);
		archive.putManyRelationship("entities", this.entities);
		
		
		List<String> vehiclesClassList = new ArrayList<String>();
		for (Mountable vehicle : this.vehicles) {
			vehiclesClassList.add(vehicle.getClass().getName());
		}
		archive.putAttributeList("vehiclesClassList", vehiclesClassList);
		archive.putManyRelationship("vehicles", this.vehicles);
		
		
		List<String> obstacleMapKeyClassList = new ArrayList<String>();
		List<String> obstacleMapValueClassList = new ArrayList<String>();
		List<Location> obstacleMapKeys = new ArrayList<Location>(this.obstacleMap.keySet());
		List<Obstacle> obstacleMapValues = new ArrayList<Obstacle>();
		for (int i = 0; i < obstacleMapKeys.size(); i++) {
			Location key = obstacleMapKeys.get(i);
			Obstacle value = this.obstacleMap.get(key);
			obstacleMapValues.add(value);
			obstacleMapKeyClassList.add(key.getClass().getName());
			obstacleMapValueClassList.add(value.getClass().getName());
		}
		archive.putAttributeList("obstacleMapKeyClassList", obstacleMapKeyClassList);
		archive.putAttributeList("obstacleMapValueClassList", obstacleMapValueClassList);
		archive.putManyRelationship("obstacleMapKeys", obstacleMapKeys);
		archive.putManyRelationship("obstacleMapValues", obstacleMapValues);
		
		
		List<String> terrainMapKeyClassList = new ArrayList<String>();
		List<String> terrainMapValueClassList = new ArrayList<String>();
		List<Location> terrainMapKeys = new ArrayList<Location>(this.terrainMap.keySet());
		List<Terrain> terrainMapValues = new ArrayList<Terrain>();
		for (int i = 0; i < terrainMapKeys.size(); i++) {
			Location key = terrainMapKeys.get(i);
			Terrain value = this.terrainMap.get(key);
			terrainMapValues.add(value);
			terrainMapKeyClassList.add(key.getClass().getName());
			terrainMapValueClassList.add(value.getClass().getName());
		}
		archive.putAttributeList("terrainMapKeyClassList", terrainMapKeyClassList);
		archive.putAttributeList("terrainMapValueClassList", terrainMapValueClassList);
		archive.putManyRelationship("terrainMapKeys", terrainMapKeys);
		archive.putManyRelationship("terrainMapValues", terrainMapValues);
		
		
		List<String> decalMapKeyClassList = new ArrayList<String>();
		List<String> decalMapValueClassList = new ArrayList<String>();
		List<Location> decalMapKeys = new ArrayList<Location>(this.decalMap.keySet());
		List<Decal> decalMapValues = new ArrayList<Decal>();
		for (int i = 0; i < decalMapKeys.size(); i++) {
			Location key = decalMapKeys.get(i);
			Decal value = this.decalMap.get(key);
			decalMapValues.add(value);
			decalMapKeyClassList.add(key.getClass().getName());
			decalMapKeyClassList.add(value.getClass().getName());
		}
		archive.putAttributeList("decalMapKeyClassList", decalMapKeyClassList);
		archive.putAttributeList("decalMapValueClassList", decalMapValueClassList);
		archive.putManyRelationship("decalMapKeys", decalMapKeys);
		archive.putManyRelationship("decalMapValues", decalMapValues);
		
		
		List<String> itemMapKeyClassList = new ArrayList<String>();
		List<String> itemMapValueClassList = new ArrayList<String>();
		List<Location> itemMapKeys = new ArrayList<Location>(this.itemMap.keySet());
		List<Item> itemMapValues = new ArrayList<Item>();
		for (int i = 0; i < itemMapKeys.size(); i++) {
			Location key = itemMapKeys.get(i);
			Item value = this.itemMap.get(key);
			itemMapValues.add(value);
			itemMapKeyClassList.add(key.getClass().getName());
			itemMapValueClassList.add(value.getClass().getName());
		}
		archive.putAttributeList("itemMapKeyClassList", itemMapKeyClassList);
		archive.putAttributeList("itemMapValueClassList", itemMapValueClassList);
		archive.putManyRelationship("itemMapKeys", itemMapKeys);
		archive.putManyRelationship("itemMapValues", itemMapValues);
		
		
		List<String> projectileMapKeyClassList = new ArrayList<String>();
		List<String> projectileMapValueClassList = new ArrayList<String>();
		List<Location> projectileMapKeys = new ArrayList<Location>(this.projectileMap.keySet());
		List<Projectile> projectileMapValues = new ArrayList<Projectile>();
		for (int i = 0; i < projectileMapKeys.size(); i++) {
			Location key = projectileMapKeys.get(i);
			Projectile value = this.projectileMap.get(key);
			projectileMapValues.add(value);
			projectileMapKeyClassList.add(key.getClass().getName());
			projectileMapValueClassList.add(value.getClass().getName());
		}
		archive.putAttributeList("projectileMapKeyClassList", projectileMapKeyClassList);
		archive.putAttributeList("projectileMapValueClassList", projectileMapValueClassList);
		archive.putManyRelationship("projectileMapKeys", projectileMapKeys);
		archive.putManyRelationship("projectileMapValues", projectileMapValues);
		
		
		List<String> areaeffectMapKeyClassList = new ArrayList<String>();
		List<String> areaeffectMapValueClassList = new ArrayList<String>();
		List<Location> areaeffectMapKeys = new ArrayList<Location>(this.areaeffectMap.keySet());
		List<AreaEffect> areaeffectMapValues = new ArrayList<AreaEffect>();
		for (int i = 0; i < areaeffectMapKeys.size(); i++) {
			Location key = areaeffectMapKeys.get(i);
			AreaEffect value = this.areaeffectMap.get(key);
			areaeffectMapValues.add(value);
			areaeffectMapKeyClassList.add(key.getClass().getName());
			areaeffectMapValueClassList.add(value.getClass().getName());
		}
		archive.putAttributeList("areaeffectMapKeyClassList", areaeffectMapKeyClassList);
		archive.putAttributeList("areaeffectMapValueClassList", areaeffectMapValueClassList);
		archive.putManyRelationship("areaeffectMapKeys", areaeffectMapKeys);
		archive.putManyRelationship("areaeffectMapValues", areaeffectMapValues);
		
		
		archive.putAttribute("maxX", Integer.toString(this.maxX));
		archive.putAttribute("maxY", Integer.toString(this.maxY));
		archive.putAttribute("minX", Integer.toString(this.minX));
		archive.putAttribute("minY", Integer.toString(this.minY));
		
		return archive;
	}
	
	public void load(Archive archive) {
		super.load(archive);
		
		List<String> entitiesClassList = archive.getAttributeList("entitiesClassList");
		List<Archive> entitiesArchives = archive.getManyRelationship("entities");
		this.entities = new ArrayList<BasicEntity>();
		for (int i = 0; i < entitiesClassList.size(); i++) {
			BasicEntity entity = (BasicEntity)ModelFactory.getInstance().createInstanceWithClassName(entitiesClassList.get(i));
			entity.load(entitiesArchives.get(i));
			this.entities.add(entity);
		}
		
		List<String> vehiclesClassList = archive.getAttributeList("vehiclesClassList");
		List<Archive> vehiclesArchives = archive.getManyRelationship("vehicles");
		this.vehicles = new ArrayList<Mountable>();
		for (int i = 0; i < vehiclesClassList.size(); i++) {
			Mountable vehicle = (Mountable)ModelFactory.getInstance().createInstanceWithClassName(vehiclesClassList.get(i));
			vehicle.load(vehiclesArchives.get(i));
			this.vehicles.add(vehicle);
		}
		
		
		List<String> obstacleMapKeyClassList = archive.getAttributeList("obstacleMapKeyClassList");
		List<String> obstacleMapValueClassList = archive.getAttributeList("obstacleMapValueClassList");
		List<Archive> obstacleMapKeys = archive.getManyRelationship("obstacleMapKeys");
		List<Archive> obstacleMapValues = archive.getManyRelationship("obstacleMapValues");
		this.obstacleMap = new HashMap<Location, Obstacle>();
		for (int i = 0; i < obstacleMapKeyClassList.size(); i++) {
			String keyClass = obstacleMapKeyClassList.get(i);
			String valueClass = obstacleMapValueClassList.get(i);
			Location location = (Location)ModelFactory.getInstance().createInstanceWithClassName(keyClass);
			Obstacle obstacle = (Obstacle)ModelFactory.getInstance().createInstanceWithClassName(valueClass);
			location.load(obstacleMapKeys.get(i));
			obstacle.load(obstacleMapValues.get(i));
			this.obstacleMap.put(location, obstacle);
		}
		
		
		List<String> terrainMapKeyClassList = archive.getAttributeList("terrainMapKeyClassList");
		List<String> terrainMapValueClassList = archive.getAttributeList("terrainMapValueClassList");
		List<Archive> terrainMapKeys = archive.getManyRelationship("terrainMapKeys");
		List<Archive> terrainMapValues = archive.getManyRelationship("terrainMapValues");
		this.terrainMap = new HashMap<Location, Terrain>();
		for (int i = 0; i < terrainMapKeyClassList.size(); i++) {
			String keyClass = terrainMapKeyClassList.get(i);
			String valueClass = terrainMapValueClassList.get(i);
			Location location = (Location)ModelFactory.getInstance().createInstanceWithClassName(keyClass);
			Terrain terrain = (Terrain)ModelFactory.getInstance().createInstanceWithClassName(valueClass);
			location.load(terrainMapKeys.get(i));
			terrain.load(terrainMapValues.get(i));
			this.terrainMap.put(location, terrain);
		}
		
		
		List<String> decalMapKeyClassList = archive.getAttributeList("decalMapKeyClassList");
		List<String> decalMapValueClassList = archive.getAttributeList("decalMapValueClassList");
		List<Archive> decalMapKeys = archive.getManyRelationship("decalMapKeys");
		List<Archive> decalMapValues = archive.getManyRelationship("decalMapValues");
		this.decalMap = new HashMap<Location, Decal>();
		for (int i = 0; i < decalMapKeyClassList.size(); i++) {
			String keyClass = decalMapKeyClassList.get(i);
			String valueClass = decalMapValueClassList.get(i);
			Location location = (Location)ModelFactory.getInstance().createInstanceWithClassName(keyClass);
			Decal decal = (Decal)ModelFactory.getInstance().createInstanceWithClassName(valueClass);
			location.load(decalMapKeys.get(i));
			decal.load(decalMapValues.get(i));
			this.decalMap.put(location, decal);
		}
		
		
		List<String> itemMapKeyClassList = archive.getAttributeList("itemMapKeyClassList");
		List<String> itemMapValueClassList = archive.getAttributeList("itemMapValueClassList");
		List<Archive> itemMapKeys = archive.getManyRelationship("itemMapKeys");
		List<Archive> itemMapValues = archive.getManyRelationship("itemMapValues");
		this.itemMap = new HashMap<Location, Item>();
		for (int i = 0; i < itemMapKeyClassList.size(); i++) {
			String keyClass = itemMapKeyClassList.get(i);
			String valueClass = itemMapValueClassList.get(i);
			Location location = (Location)ModelFactory.getInstance().createInstanceWithClassName(keyClass);
			Item item = (Item)ModelFactory.getInstance().createInstanceWithClassName(valueClass);
			location.load(itemMapKeys.get(i));
			item.load(itemMapValues.get(i));
			this.itemMap.put(location, item);
		}
		
		
		List<String> projectileMapKeyClassList = archive.getAttributeList("projectileMapKeyClassList");
		List<String> projectileMapValueClassList = archive.getAttributeList("projectileMapValueClassList");
		List<Archive> projectileMapKeys = archive.getManyRelationship("projectileMapKeys");
		List<Archive> projectileMapValues = archive.getManyRelationship("projectileMapValues");
		this.projectileMap = new HashMap<Location, Projectile>();
		for (int i = 0; i < projectileMapKeyClassList.size(); i++) {
			String keyClass = projectileMapKeyClassList.get(i);
			String valueClass = projectileMapValueClassList.get(i);
			Location location = (Location)ModelFactory.getInstance().createInstanceWithClassName(keyClass);
			Projectile projectile = (Projectile)ModelFactory.getInstance().createInstanceWithClassName(valueClass);
			location.load(projectileMapKeys.get(i));
			projectile.load(projectileMapValues.get(i));
			this.projectileMap.put(location, projectile);
		}
		
		
		List<String> areaeffectMapKeyClassList = archive.getAttributeList("areaeffectMapKeyClassList");
		List<String> areaeffectMapValueClassList = archive.getAttributeList("areaeffectMapValueClassList");
		List<Archive> areaeffectMapKeys = archive.getManyRelationship("areaeffectMapKeys");
		List<Archive> areaeffectMapValues = archive.getManyRelationship("areaeffectMapValues");
		this.areaeffectMap = new HashMap<Location, AreaEffect>();
		for (int i = 0; i < areaeffectMapKeyClassList.size(); i++) {
			String keyClass = areaeffectMapKeyClassList.get(i);
			String valueClass = areaeffectMapValueClassList.get(i);
			Location location = (Location)ModelFactory.getInstance().createInstanceWithClassName(keyClass);
			AreaEffect areaEffect = (AreaEffect)ModelFactory.getInstance().createInstanceWithClassName(valueClass);
			location.load(areaeffectMapKeys.get(i));
			areaEffect.load(areaeffectMapValues.get(i));
			this.areaeffectMap.put(location, areaEffect);
		}
		
		
		this.maxX = Integer.parseInt(archive.getAttribute("maxX"));
		this.maxY = Integer.parseInt(archive.getAttribute("maxY"));
		this.minX = Integer.parseInt(archive.getAttribute("minX"));
		this.minY = Integer.parseInt(archive.getAttribute("minY"));
		
	}
	
}
